<?php


namespace App\Services;


use App\Models\Group;
use App\Utils\Code;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class GroupService extends BaseService
{
    /**
     * 创建数据
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function store(array $params) {
        if (!$this->checkParams($params)){
            throw new \Exception('请求参数验证不通过', Code::PARAMETER_ERROR);
        }
        $model = new Group();
        if (Group::where('group_name', $params['group_name'])->first()) {
            throw new \Exception('该分组已经存在', Code::EXIST_REPEAT);
        }
        $model->group_name = $params['group_name'];
        if (isset($params['description'])) {
            $model->description = $params['description'];
        }
        if (isset($params['sort'])){
            $model->sort = (int)$params['sort'];
        }
        if (isset($params['status'])){
            $model->status = (int)$params['status'];
        }
        if (isset($params['menus']) && $params['menus']) {
            $model = \DB::transaction(function () use ($model, $params){
                $model->save();
                // 同步中间关系
                $model->menus()->sync($params['menus']);
                return $model;
            });
        } else {
            $model->save();
        }
        return $this->show($model->group_id, false);
    }

    /**
     * 数据信息
     * @param $id
     * @param bool $simple
     * @param bool $abnormal
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function show($id, $simple = true, $abnormal = true) {
        $model = Group::where('group_id', $id);
        if (!$simple){
            $model = $model->with(['menus' => function(BelongsToMany $belongsToMany){
                $belongsToMany->select(['bind_group_menu.menu_id', 'menu_name', 'pid']);
            }]);
        }
        $model = $model->first();
        if (!$model && $abnormal){
            throw new \Exception('不存在的分组ID主键', Code::EMPTY_DATA);
        }
        return $model;
    }

    /**
     * 更新数据
     * @param $id
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function update($id, array $params) {
        if (!$this->checkParams($params, true)){
            throw new \Exception('请求参数验证不通过', Code::PARAMETER_ERROR);
        }
        $model = $this->show($id, true, true);
        if (isset($params['group_name']) && $params['group_name']) {
            $model->group_name = $params['group_name'];
        }
        if (isset($params['description'])) {
            $model->description = $params['description'];
        }
        if (isset($params['sort']) && is_numeric($params['sort'])) {
            $model->sort = $params['sort'];
        }
        if (isset($params['status']) && is_numeric($params['status'])) {
            $model->status = $params['status'];
        }
        if (isset($params['menus'])) {
            if (is_array($params['menus']) && $params['menus']) {
                $model = \DB::transaction(function () use ($model, $params){
                    // 同步中间关系
                    $model->menus()->sync($params['menus']);
                    $model->save();
                    return $model;
                });
            } else {
                \DB::table('bind_group_menu')->where('group_id', (int)$id)->delete();
            }

        }
        $model->save();
        return $this->show($model->group_id, false);
    }

    /**
     * 删除数据
     * @param $id
     * @return mixed
     * @throws \Exception
     */
    public function destroy($id) {
        if (!$this::$admin) {
            throw new \Exception('你没有权限删除分组', Code::LACK_OF_CONDITIONS);
        }
        $model = $this->show($id, true, true);
        return \DB::transaction(function () use ($model) {
            \DB::table('bind_group_menu')->where('group_id', $model->group_id)->delete();
            return $model->delete();
        });
    }

    /**
     * 数据分页
     * @param array $params
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function paginate(array $params = []) {
        $model = Group::orderBy('sort', 'asc');
        if (isset($params['keyword']) && $params['keyword']) {
            $model = $model->where(function (Builder $builder) use ($params) {
                $builder->where('group_name', 'like', $params['keyword'].'%')
                    ->orWhere('group_id', (int)$params['keyword']);
            });
        }
        if (isset($params['status']) && is_numeric($params['status'])) {
            $model = $model->where('status', (int)$params['status']);
        }
        return $model->orderBy('sort', 'asc')->orderBy('group_id', 'desc')
            ->paginate(isset($params['per_page']) ? (int)$params['per_page'] : null);
    }

    /**
     * 验证参数
     * @param array $params
     * @param bool $isUpdate
     * @return array
     * @throws \Exception
     */
    private function checkParams(array $params, $isUpdate = false){
        $rules = [
            'group_name' => ['bail', 'required', 'string', 'between:2,6'],
            'sort' => ['bail', 'integer'],
            'status' => ['bail', 'integer', 'in:0,1']
        ];
        if ($isUpdate){
            // 删除必选条件
            foreach ($rules as $field => &$rule){
                if (isset($rule[1]) && $rule[1] == 'required') {
                    unset($rule[1]);
                }
            }
        }
        $validator = \Validator::make($params, $rules, [], [
            'group_name' => '分组标题',
            'sort' => '排序数值',
            'status' => '可用状态'
        ]);
        if ($validator->fails()) {
            throw new \Exception($validator->errors()->first(), Code::PARAMETER_ERROR);
        }
        return $params;
    }
}
